package com.mouse.hxsj.service;

import com.mouse.damo.micro.*;
import com.mouse.damo.util.LogUtil;
import com.mouse.haoi.HaoiUtil;
import com.mouse.haoi.entity.FileParam;
import com.mouse.haoi.service.CustomService;
import com.mouse.hxsj.constants.ComPool;
import com.mouse.hxsj.constants.SystemParams;
import com.mouse.hxsj.entity.common.Point;
import com.mouse.hxsj.entity.enums.RoleEnum;
import com.mouse.hxsj.util.CmdUtil;
import com.mouse.hxsj.util.DateUtil;
import com.mouse.hxsj.util.StringUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

@Slf4j
@Component
public class LoginService {
    private final static CustomService customService = new CustomService();
    /**
     * 2500916498
     * 3454864823
     * 2160578894
     * 440785199407290033
     */
    /**
     * 获取已登录的句柄
     *
     * @return
     */
    private List<Integer> hasLoginHwnd(Window window, boolean logFlag) {
        String hwnds = window.findWindows("QQ幻想世界", "CLIENT");
        if (logFlag) log.info("已登录未筛选句柄:{}", hwnds);
        String[] split = hwnds.split(",");
        if (split.length == 1 && "".equals(split[0])) return new ArrayList<>();
        List<Integer> result = Arrays.asList(split).stream()
                .map(str -> Integer.valueOf(str)).filter(hwnd -> {
                    String windowTitle = window.getWindowTitle(hwnd);
                    if (logFlag) log.info(window.getWindowTitle(hwnd));
                    if ("QQ幻想世界".equals(windowTitle)) return true;
                    else return false;
                }).collect(Collectors.toList());
        if (logFlag) log.info("已登录筛选句柄:{}", String.join(",",
                result.stream().map(integer -> String.valueOf(integer)).collect(Collectors.toList())));
        return result;
    }

    private void deleteNoLogin(Window window) {
        String hwnds = window.findWindows("QQ幻想世界登录程序");
        log.info("未登录句柄:{}", hwnds);
        String[] split = hwnds.split(",");
        if (split.length == 1 && "".equals(split[0])) return;
        Arrays.asList(split).forEach(s -> window.setWindowDestroy(Integer.parseInt(s)));

    }

    public void login(String uesrName, String password,
                      Point point1, Point point2, RoleEnum roleEnum) {
        log.info("开始登录");
        Com com = new Com();
        Com otherCom = new Com();
        com.setResourcePath(SystemParams.sourcePath);
        Window window = new Window(com);
        Mouse mouse = new Mouse(com);
        Press press = new Press(com);
        FindPic findPic = new FindPic(com);
        LoginService loginService = new LoginService();
        loginService.deleteNoLogin(window);
        List<Integer> hwndList = loginService.hasLoginHwnd(window, true);
        CmdUtil.executeCmd(SystemParams.exePath);
        List<String> newHwnd = new ArrayList<>();
        log.info("判断启动客户端");
        boolean loginClientFlag = customService.loop(20, () -> {
            String hwnds = window.findWindows("QQ幻想世界登录程序");
            LogUtil.logNotNull(hwnds);
            boolean flag = StringUtil.isNotBlank(hwnds);
            if (flag) newHwnd.add(hwnds);
            return flag;
        });
        if (!loginClientFlag) return;
        String hwndStr = newHwnd.get(0);
        if (hwndStr.split(",").length > 1) {
            log.info("出现相同标题不同句柄：{}", hwndStr);
            log.info("重新登录");
            login(uesrName, password, point1, point2, roleEnum);
            return;
        }
        Integer newHwndInt = Integer.valueOf(hwndStr);
        boolean bindFlag = com.bind(newHwndInt);
        window.setWindowState(newHwndInt, 5);
        log.info("绑定窗口{}", bindFlag);
        log.info("判断是否有进入游戏按钮");
        boolean enterPicFlag = customService.loop(30, () -> {
            String pics = findPic.findPics(603, 504, 820, 560,
                    "login/进入游戏.bmp|login/进入游戏1.bmp", "203040", 0.9, 0);
            LogUtil.logNotNull(pics);
            return StringUtil.isNotBlank(pics);
        });
        if (!enterPicFlag) return;
        mouse.mouseClick(710, 529, true);
        log.info("判断是否有登录按钮");
        boolean loginPicFlag = customService.loop(15, () -> {
            String pics = findPic.findPics(331, 504, 544, 565,
                    "login/登录.bmp|login/登录1.bmp", "203040", 0.9, 0);
            LogUtil.logNotNull(pics);
            return StringUtil.isNotBlank(pics);
        });
        if (!loginPicFlag) return;
        mouse.mouseClick(462, 254, true);
        IntStream.range(0, 20).forEach(index -> press.keyPressTime(Press.BACKSPACE, 10));
        Sleep.sleep(100);
        window.sendString(newHwndInt, uesrName);
        mouse.mouseClick(416, 327, true);
        Sleep.sleep(100);
        window.sendString(newHwndInt, password);
//        press.keyPress(Press.ENTER);
        mouse.mouseClick(438, 534, true);
        //验证码
        List<Integer> list = new ArrayList<>();
        list.add(0);
        boolean yzmFlag = customService.loop(30, () -> {
            if(list.get(0)>1)return true;
            int yznmHwnd = window.findWindow(0, "TWINCONTROL", "");
            if (yznmHwnd > 0 && yznmHwnd != newHwndInt) {
                boolean yzmConfirmFlag = customService.loop(15, () -> {
                    boolean yzmPicFlag = getYzmPic(otherCom, newHwndInt, yznmHwnd);
                    if (!yzmPicFlag) return false;
                    list.set(0,list.get(0)+1);
                    return true;
                });
            } else {
                String pics = findPic.findPics(93, 156, 545, 243,
                        "login/选区.bmp", "203040", 0.9, 0);
                LogUtil.logNotNull(pics);
                if (StringUtil.isNotBlank(pics)) return true;
            }
            return false;
        });
        log.info("判断是否有确认选择按钮");
        boolean confirmPicFlag = customService.loop(15, () -> {
            String pics = findPic.findPics(93, 156, 545, 243,
                    "login/选区.bmp", "203040", 0.9, 0);
            LogUtil.logNotNull(pics);
            return StringUtil.isNotBlank(pics);
        });
        //选区
        if (!confirmPicFlag) return;
        mouse.mouseClick(point1.getX(), point1.getY(), true);
        Sleep.sleep(500);
        mouse.mouseClick(point2.getX(), point2.getY(), true);
        Sleep.sleep(200);
        mouse.mouseClick(679, 558, true);
        com.unbind();
        if (roleEnum == null || roleEnum.getRoleNum() == 0) return;
        log.info("判断选取角色");
        List<Integer> roleHwndList = new ArrayList<>();
        Sleep.sleep(100);
        boolean roleFlag = customService.loop(30, () -> {
            List<Integer> hwndList1 = loginService.hasLoginHwnd(window, false);
            Integer roleHwnd = null;
            for (Integer hwnd : hwndList1) {
                if (!hwndList.contains(hwnd)) {
                    roleHwnd = hwnd;
                    roleHwndList.add(hwnd);
                    break;
                }
            }
            return roleHwnd != null;
        });
        if (!roleFlag) return;
        boolean bindRoleFlag = com.bind(roleHwndList.get(0));
        log.info("绑定角色窗口{} {}", roleHwndList.get(0), bindRoleFlag);
        log.info("绑定进入游戏按钮");
        boolean PicFlag = customService.loop(10, () -> {
            String pics = findPic.findPics(5, 291, 249, 558,
                    "login/选择角色.bmp", "203040", 0.8, 0);
            LogUtil.logNotNull(pics);
            return StringUtil.isNotBlank(pics);
        });
        if (!PicFlag) return;
        Point point = roleEnum.getPoint();
        mouse.mouseClick(point.getX(), point.getY(), true);
        Sleep.sleep(50);
        mouse.mouseClick(909, 505, true);
        log.info("登录成功");
        ComPool.add(com, uesrName);
    }

    private boolean getYzmPic(Com com, Integer hwnd, Integer newHwnd) {
        Window window = new Window(com);
        FindPic findPic = new FindPic(com);
        Mouse mouse = new Mouse(com);
        window.setWindowState(hwnd, 1);
        Sleep.sleep(200);
        int[] pic = findPic.findPic(109, 64, 1203, 690,
                SystemParams.sourcePath + "/login/验证码.bmp", "203040", 0.8, 0);
        if (pic[0] == -1) return false;
        log.info("存在验证码");
        File file = new File(com);
        String picName = SystemParams.sourcePath + "/yzm/" + DateUtil.toDateStr(new Date(), "yyyy-MM-dd HH-mm-ss") + ".png";
        boolean imageFlag = file.screenImage(pic[1], pic[2] - 56, pic[1] + 132, pic[2] - 2, picName);
        if (!imageFlag) return false;
        log.info("验证码图片路径:{}", picName);
        FileParam fileParam = new FileParam();
        fileParam.setUserStr("893656121|ZQOH5SM4I2M1OD8N");
        fileParam.setGameID("2004");
        fileParam.setTimeOut("600");
        fileParam.setRebate("3307|CF761DF62A838FEA");
        fileParam.setFilePath(picName);
        String id = HaoiUtil.sendFile(fileParam);
        log.info("好爱答题id：{}", id);
        String answer = HaoiUtil.getAnswer(id);
        log.info("好爱答题答案：{}", id);
        window.setWindowState(hwnd, 1);
        Sleep.sleep(100);
        mouse.mouseClick(pic[1] + 181, pic[2] - 20, true);
        window.sendString(newHwnd, answer);
        Sleep.sleep(50);
        mouse.mouseClick(pic[1] + 46, pic[2] + 37, true);
        return true;
    }

    public static void main(String[] args) {
        Com com = new Com();
        com.setResourcePath("D:/damo");
        Window window = new Window(com);
        Mouse mouse = new Mouse(com);
        Press press = new Press(com);
        FindPic findPic = new FindPic(com);
        LoginService loginService = new LoginService();
        loginService.deleteNoLogin(window);
        List<Integer> hwndList = loginService.hasLoginHwnd(window, true);
        CmdUtil.executeCmd("D:\\腾讯游戏\\qq幻想世界\\qqhxsj.exe");
        List<String> newHwnd = new ArrayList<>();
        log.info("判断启动客户端");
        boolean loginClientFlag = customService.loop(20, () -> {
            String hwnds = window.findWindows("QQ幻想世界登录程序");
            LogUtil.logNotNull(hwnds);
            boolean flag = StringUtil.isNotBlank(hwnds);
            if (flag) newHwnd.add(hwnds);
            return flag;
        });
        Integer newHwndInt = Integer.valueOf(newHwnd.get(0));
        boolean bindFlag = com.bind(newHwndInt);
        window.setWindowState(newHwndInt, 5);
        log.info("绑定窗口{}", bindFlag);
        log.info("判断是否有进入游戏按钮");
        boolean enterPicFlag = customService.loop(30, () -> {
            String pics = findPic.findPics(603, 504, 820, 560,
                    "login/进入游戏.bmp|login/进入游戏1.bmp", "203040", 0.9, 0);
            LogUtil.logNotNull(pics);
            return StringUtil.isNotBlank(pics);
        });

        mouse.mouseClick(710, 529, true);
        log.info("判断是否有登录按钮");
        boolean loginPicFlag = customService.loop(10, () -> {
            String pics = findPic.findPics(331, 504, 544, 565,
                    "login/登录.bmp|login/登录1.bmp", "203040", 0.9, 0);
            LogUtil.logNotNull(pics);
            return StringUtil.isNotBlank(pics);
        });
        mouse.mouseClick(462, 254, true);
        IntStream.range(0, 20).forEach(index -> press.keyPressTime(Press.BACKSPACE, 10));
//        window.sendString(newHwndInt,"1006997702");
//        window.sendString(newHwndInt,"2160578894");
//        window.sendString(newHwndInt,"707033141");
//        window.sendString(newHwndInt,"2500916498");
//        window.sendString(newHwndInt,"3454864823");
//        window.sendString(newHwndInt, "893656121");
//        window.sendString(newHwndInt, "167433937");
        window.sendString(newHwndInt, "215402667");
        mouse.mouseClick(416, 327, true);
//        window.sendString(newHwndInt,"893656121");
        window.sendString(newHwndInt, "893656121.");
//        window.sendString(newHwndInt,"5201314a");
        mouse.mouseClick(438, 534, true);
        log.info("判断是否有确认选择按钮");
        boolean confirmPicFlag = customService.loop(10, () -> {
            String pics = findPic.findPics(93, 156, 545, 243,
                    "login/选区.bmp", "203040", 0.9, 0);
            LogUtil.logNotNull(pics);
            return StringUtil.isNotBlank(pics);
        });
        //选区
        mouse.mouseClick(380, 178, true);
        Sleep.sleep(50);
        mouse.mouseClick(266, 445, true);
        Sleep.sleep(50);
        mouse.mouseClick(679, 558, true);
        com.unbind();
        log.info("判断选取角色");
        List<Integer> roleHwndList = new ArrayList<>();
        Sleep.sleep(100);
        boolean roleFlag = customService.loop(30, () -> {
            List<Integer> hwndList1 = loginService.hasLoginHwnd(window, false);
            Integer roleHwnd = null;
            for (Integer hwnd : hwndList1) {
                if (!hwndList.contains(hwnd)) {
                    roleHwnd = hwnd;
                    roleHwndList.add(hwnd);
                    break;
                }
            }
            return roleHwnd != null;
        });
        boolean bindRoleFlag = com.bind(roleHwndList.get(0));
        log.info("绑定角色窗口{} {}", roleHwndList.get(0), bindRoleFlag);
        log.info("绑定进入游戏按钮");
        boolean PicFlag = customService.loop(10, () -> {
            String pics = findPic.findPics(5, 291, 249, 558,
                    "login/选择角色.bmp", "203040", 0.8, 0);
            LogUtil.logNotNull(pics);
            return StringUtil.isNotBlank(pics);
        });
//        Sleep.sleep(3500);
//        mouse.mouseClick(880, 124, true);
//        mouse.mouseClick(909, 505, true);
        log.info("登录成功");
    }

    private static void t(Com com) {
        for (int i = 0; i < 10; i++) {
            new Mouse(com).mouseClick(200, 200, true);
        }
    }
}
